package com.auth.aop;

import com.auth.entity.vo.OperationLogVo;
import com.auth.service.IOperationLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * @author 大忽悠
 * @create 2023/2/9 12:16
 */
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class OperationLogAspect {
    private final IOperationLogService iOperationLogService;

    @Around(value = "@annotation(opLog)")
    public Object aroundLog(ProceedingJoinPoint joinPoint,OpLog opLog) throws Throwable {
        Object[] methodArgs = joinPoint.getArgs();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Object res = joinPoint.proceed();
        //方法执行成功后,才会记录操作日志
        operationLog(methodArgs,method,opLog);
        return res;
    }

    /**
     * 日志记录失败就跳过记录--捕获异常,不进行抛出
     */
    private void operationLog(Object[] methodArgs, Method method, OpLog opLog) {
         try{
             Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
             UserDetails userDetails = (UserDetails) authentication.getPrincipal();
             String content = String.format(opLog.desc(), methodArgs);
             OperationLogVo operationLogVo = OperationLogVo.builder().operationName(userDetails.getUsername()).operationContent(content).build();
             iOperationLogService.saveOperationLog(operationLogVo);
         } catch (Exception e){
            log.error("操作日志记录过程中产生错误: ",e);
            throw e;
         }
    }
}
